package com.mallcai.bigdata.ladon.datasource;

import com.cake.bigdata.starter.exception.category.BusinessException;
import com.mallcai.bigdata.ladon.dpl.entity.common.Datasource;
import com.mallcai.bigdata.ladon.dpl.vo.DataType;
import com.mallcai.bigdata.ladon.vo.BatchUpdateParam;
import com.mallcai.bigdata.ladon.vo.ColumnVo;
import com.mallcai.bigdata.ladon.vo.QueryParam;
import com.mallcai.bigdata.ladon.vo.TableVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by oneape<oneape15@163.com>
 * Created 2019-06-10 20:31.
 * Modify:
 */
@Slf4j
public class MySQLHandler extends AbstractJdbcHandler {

    private static final String SHOW_ALL_TABLES = "select  table_schema, table_name, table_comment from information_schema.tables " +
            "where table_schema = :instanceName and table_type = 'BASE TABLE'";


    private static final String SHOW_ALL_COLUMNS = "select table_name, column_name, column_comment,data_type, is_nullable,  numeric_precision, numeric_scale from information_schema.columns " +
            "where table_name = :tableName ";
    /**
     * 获取数据源下的所有表信息
     *
     * @param ds Datasource
     * @return List
     */
    @Override
    public List<TableVo> getAllTables(Datasource ds) {
        AbstractDataSource dataSource = DatasourceFactory.getDataSource(ds);
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("instanceName", getInstanceName(ds.getJdbcUrl()));
        return dataSource.getNamedParameterJdbcTemplate().query(SHOW_ALL_TABLES,paramMap,(resultSet, rowNum)->{
            TableVo vo = new TableVo();
            vo.setSchema(resultSet.getString("table_schema"));
            vo.setName(resultSet.getString("table_name"));
            vo.setDesc(resultSet.getString("table_comment"));
            return vo;
        });
    }

    /**
     * 获取表下面的所有字段信息
     *
     * @param ds        Datasource
     * @param tableName String
     * @return List
     */
    @Override
    public List<ColumnVo> getColumns(Datasource ds, String tableName) {
        AbstractDataSource dataSource = DatasourceFactory.getDataSource(ds);
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("tableName", tableName);
        return dataSource.getNamedParameterJdbcTemplate().query(SHOW_ALL_COLUMNS,paramMap,(resultSet, rowNum)->{
            String columnName = resultSet.getString("column_name");
            String columnComment = resultSet.getString("column_comment");
            String dataType = resultSet.getString("data_type");
            String isNullable = resultSet.getString("is_nullable");
            int numericPrecision = resultSet.getInt("numeric_precision");
            int numericScale = resultSet.getInt("numeric_scale");
            ColumnVo vo = new ColumnVo();
            vo.setName(columnName);
            vo.setDesc(columnComment);
            vo.setNullable("YES".equalsIgnoreCase(isNullable));
            vo.setType(DataType.parse(dataType).getCode());
            vo.setOriginalType(dataType);
            vo.setTableName(tableName);
            vo.setPrecision(numericPrecision);
            vo.setScale(numericScale);
            return vo;
        });
    }


    private String getInstanceName(String url){
        int index = url.indexOf("?");
        url = url.substring(0, (index == -1 ? url.length() : index));
        index = url.lastIndexOf("/");
        return url.substring(index+1);
    }

    @Override
    public void execute(Datasource ds, QueryParam queryParam) {
        AbstractDataSource dataSource = DatasourceFactory.getDataSource(ds);
        if (dataSource == null) {
            throw new BusinessException("无效的数据源");
        }
        new JdbcTemplate(dataSource.getInnerDataSource()).execute(queryParam.getRawSql());
    }


    @Override
    public int[][] batchUpdate(Datasource ds, BatchUpdateParam param) {
        AbstractDataSource dataSource = DatasourceFactory.getDataSource(ds);
        if (dataSource == null) {
            throw new BusinessException("无效的数据源");
        }
        return new JdbcTemplate(dataSource.getInnerDataSource()).batchUpdate(param.getSql(), param.getParamList(), param.getBatchSize(), param.getParameterizedSetter());
    }

}
